# 导入django的分页类
from datetime import date

from django.core.paginator import Paginator
from django.http import JsonResponse
from django.shortcuts import render
from haystack.views import SearchView

from apps.contents.utils import get_category
from apps.goods.models import SKU,GoodsCategory,GoodsVisitCount
# Create your views here.
from django.views import View


# 列表数据处理
class GoodsView(View):
    # id是前端传递的三级分类id
    def get(self,request,id):
        # 1、获取前端传递的分页数据和排序数据，查询字符串形式传递的
        page = request.GET.get('page')
        page_size = request.GET.get('page_size')
        ordering = request.GET.get('ordering')

        # 2、根据前端传递到的分类id查询sku表获取对应的商品数据，按照传递的排序数据对所有商品进行排序
        skus = SKU.objects.filter(category_id=id, is_launched=True).order_by(ordering)
        # 3、对商品数据进行分页处理
        # 初始化分页类，生成分页对象，需传递两个参数，第一个要分页的数据，第二个分页后每一页数量
        paginator = Paginator(skus,page_size)
        # 提取分页数据，将页数传递进去
        try:
            page_skus = paginator.page(page)
        except:
            return JsonResponse({'code':400,},status=400)
        # 4、根据传递的分页数据进行响应分页数据获取
        data_list = []
        for page_sku in page_skus:
            data_list.append({
                'id': page_sku.id,
                'default_image_url': page_sku.default_image.url,
                'name': page_sku.name,
                'price': page_sku.price,
            })

        # 获取当前商品的分类数据，构造面包屑导航数据，查询商品分类表
        cat3 = GoodsCategory.objects.get(id=id)
        # 根据三级分类数据获取二级分类数据
        cat2 = cat3.parent
        # 根据二级分类数据获取一级分类数据
        cat1 = cat2.parent

        return JsonResponse({
            'code':0,
            'errmsg':'ok',
            'breadcrumb':{
                'cat1':cat1.name,
                'cat2':cat2.name,
                'cat3':cat3.name,
            },
            'list':data_list,
            'count':paginator.num_pages
        })


# 热销商品
class GoodsHotView(View):
    def get(self,request,id):
        # 根据前端传递的分类id查询sku表获取对应的商品数据，按照销量进行排序。数据的控制返回两条数据
        skus = SKU.objects.filter(category_id=id, is_launched=True).order_by('sales')[0:2]
        # 构造返回数据的结构
        data_list = []
        for sku in skus:
            data_list.append({
                'id': sku.id,
                'default_image_url': sku.default_image.url,
                'name': sku.name,
                'price': sku.price,
            })

        # 返回结果
        return JsonResponse({
            'code': 0,
            'errmsg': 'ok',
            'hot_skus': data_list,
        })


# 搜索服务，需要继承Haystack客户端的类视图
class SearchGoodsView(SearchView):

    # 重写客户单返回结果方法，按照json形式进行返回
    def create_response(self):

        # 获取搜索结果
        context = self.get_context()

        # 通过context获取查询后的商品数据
        skus = context['page'].object_list
        data_list = []
        for sku in skus:
            data_list.append({
                'id': sku.object.id,
                'name': sku.object.name,
                'price': sku.object.price,
                'default_image_url': sku.object.default_image.url,
                'searchkey': context.get('query'),
                'page_size': context['page'].paginator.num_pages,  # 页数
                'count': context['page'].paginator.count  # 总数
            })
        # 返回列表，不再需要进行字典类型检查
        return JsonResponse(data_list, safe=False)


class DetailGoodsView(View):
    def get(self,request,id):
        # 1、根据商品id查询sku表获取商品对象
        try:
            sku = SKU.objects.get(id = id)
        except:
            return JsonResponse({'code':400,'errmsg':'商品不存在'})
        # 2、调用封装方法，获取商品分类信息
        categories = get_category()
        # 3、获取面包屑导航数据
        # 获取当前商品的分类数据，构造面包屑导航数据。查询商品分类表
        cat3 = GoodsCategory.objects.get(
            id=sku.category.id)  # 传递分类id,通过sku.category.id 获取到sku对应的商品分类的对象，进而获取商品分类id。sku副表，商品分类是主表
        # 根据三级分类数据获取二级分类
        cat2 = cat3.parent
        # 根据二级分类数据获取一级分类
        cat1 = cat2.parent

        # 对商品的选项进行选中展示
        # 要知道当前商品的选项,先获取当前商品的规格，然后根据商品的规格获取对应选项
        sku_specs = sku.specs.order_by('spec_id')
        sku_key=[]
        for spec in sku_specs:
            sku_key.append(spec.option_id)

        # 获取所有商品的规格选项，和当前商品进行比对
        # 先获取所有sku商品，所有商品和spu有关联关系
        spu = sku.spu
        skus = SKU.objects.filter(spu = spu)
        sku_spec_option={}
        for sku_data in skus:
            s_key = []
            sku_specs = sku_data.specs.order_by('spec_id')
            for spec in sku_specs:
                s_key.append(spec.option_id)
            sku_spec_option[tuple(s_key)] = sku_data.id


        # 4、渲染规格数据
        # 获取当前商品的所有规格，需要得到当前商品的spu
        spu = sku.spu  # 副表查询主表
        goods_specs = spu.specs.all()    # 主表查询副表


        # 5、遍历规格指定规格选项
        for spec in goods_specs:
            for index, spec in enumerate(goods_specs):
                # 原有规格赋值
                key = sku_key[:]  # 所有下表的数据赋值
                # 根据规格查询该规格下的所有选项  主表查询副表
                spec_options = spec.options.all()
                # 给当前选项赋值sku商品id
                for option in spec_options:
                    key[index] = option.id
                    option.sku_id = sku_spec_option.get(tuple(key))
                # 在spec中增加一个属性spec_options，spec是遍历的商品规格对象
                spec.spec_options = spec_options

        # 6、构造渲染数据
        context = {
            'sku':sku,
            'categories':categories,
            'breadcrumb': {  # 面包屑数据
                'cat1': cat1.name,
                'cat2': cat2.name,
                'cat3': cat3.name
            },
            'specs':goods_specs
        }

        response = render(request, 'detail.html', context=context)
        # 将首页渲染的html数据写入前端的index.html文件目录下
        # 打开前端目录下的index.html文件
        with open('/home/ubuntu/Desktop/front_end_pc/goods/%d.html % sku.id', 'w', encoding='utf-8') as f:
            f.write(response.content.decode())
        return JsonResponse({'code': 0})


# 商品分类访问量统计
class DetailVisitView(View):
    def post(self,request,id):
        # 1、根据分类id查询当前分类
        try:
            goods_category = GoodsCategory.objects.get(id = id)
        except:
            return JsonResponse({'code':400,'errmsg':'分类不存在'},status = 400)
        # 2、获取当天的日期
        day = date.today()
        # 3、根据分类查询当天日期的商品分类统计表，以时间作为查询条件
        try:
            # 关联查询
            goodvisit = goods_category.goodsvisitcount_set.get(date=day)
        except:
            # 4、不存在中的生成新的商品分类统计表对象
            goodvisit = GoodsVisitCount()
        # 5、商品分类统计表中的访问数据的累加和分类赋值
        goodvisit.count += 1
        goodvisit.category = goods_category
        goodvisit.save()
        return JsonResponse({'code':0,'errmsg':'ok'})